package com.wgb.movie.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wgb.movie.common.ErrorCode;
import com.wgb.movie.constant.CommonConstant;
import com.wgb.movie.exception.ThrowUtils;
import com.wgb.movie.mapper.MovieShowMapper;
import com.wgb.movie.model.dto.movieShow.MovieShowQueryRequest;
import com.wgb.movie.model.entity.*;

import com.wgb.movie.model.vo.MovieShowVO;
import com.wgb.movie.model.vo.MovieVO;
import com.wgb.movie.model.vo.TheaterVO;
import com.wgb.movie.model.vo.UserVO;
import com.wgb.movie.service.MovieService;
import com.wgb.movie.service.MovieShowService;
import com.wgb.movie.service.TheaterService;
import com.wgb.movie.service.UserService;
import com.wgb.movie.utils.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 上映服务实现
 *
 * @author <a href="https://github.com/liyupi">程序员鱼皮</a>
 * @from <a href="https://www.code-nav.cn">编程导航学习圈</a>
 */
@Service
@Slf4j
public class MovieShowServiceImpl extends ServiceImpl<MovieShowMapper, MovieShow> implements MovieShowService {

    @Resource
    private UserService userService;

    /**
     * 校验数据
     *
     * @param movieShow
     * @param add      对创建的数据进行校验
     */
    @Override
    public void validMovieShow(MovieShow movieShow, boolean add) {
        ThrowUtils.throwIf(movieShow == null, ErrorCode.PARAMS_ERROR);
        // todo 从对象中取值


        Long theaterId = movieShow.getTheaterId();
        Date showTime = movieShow.getShowTime();
        Integer languageType = movieShow.getLanguageType();
        Integer hallType = movieShow.getHallType();
        BigDecimal price = movieShow.getPrice();



        // 创建数据时，参数不能为空
        if (add) {
            // todo 补充校验规则
            ThrowUtils.throwIf(theaterId<=0, ErrorCode.PARAMS_ERROR,"theaterId不合法");
            ThrowUtils.throwIf(showTime==null, ErrorCode.PARAMS_ERROR,"showTime不能空");
            ThrowUtils.throwIf(languageType<0||languageType==null, ErrorCode.PARAMS_ERROR,"languageType不合法");
            ThrowUtils.throwIf(hallType<0||hallType==null, ErrorCode.PARAMS_ERROR,"hallType不合法");
            ThrowUtils.throwIf(price==null||price.compareTo(BigDecimal.ZERO)<=0, ErrorCode.PARAMS_ERROR,"price不合法");
        }
        // 修改数据时，有参数则校验
        // todo 补充校验规则

    }

    /**
     * 获取查询条件
     *
     * @param movieShowQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<MovieShow> getQueryWrapper(MovieShowQueryRequest movieShowQueryRequest) {
        QueryWrapper<MovieShow> queryWrapper = new QueryWrapper<>();
        if (movieShowQueryRequest == null) {
            return queryWrapper;
        }
        // todo 从对象中取值
        Long id = movieShowQueryRequest.getId();
        Long movieId = movieShowQueryRequest.getMovieId();
        Long theaterId = movieShowQueryRequest.getTheaterId();
        Date showTime = movieShowQueryRequest.getShowTime();
        Integer languageType = movieShowQueryRequest.getLanguageType();
        Integer hallType = movieShowQueryRequest.getHallType();



        String sortField = movieShowQueryRequest.getSortField();
        String sortOrder = movieShowQueryRequest.getSortOrder();

        // todo 补充需要的查询条件
        // 从多字段中搜索

        // 模糊查询

        // JSON 数组查询

        // 精确查询
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(movieId), "movieId", movieId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(theaterId), "theaterId", theaterId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(showTime), "showTime", showTime);
        queryWrapper.eq(ObjectUtils.isNotEmpty(languageType), "languageType", languageType);
        queryWrapper.eq(ObjectUtils.isNotEmpty(hallType), "hallType", hallType);
        // 排序规则
        queryWrapper.orderBy(SqlUtils.validSortField(sortField),
                sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }

    /**
     * 获取上映封装
     *
     * @param movieShow
     * @param request
     * @return
     */
    @Resource
    private MovieService movieService;
    @Resource
    private TheaterService theaterService;
    @Override
    public MovieShowVO getMovieShowVO(MovieShow movieShow, HttpServletRequest request) {
        // 对象转封装类
        MovieShowVO movieShowVO = MovieShowVO.objToVo(movieShow);
        Movie movie = movieService.getById(movieShowVO.getMovieId());
        MovieVO movieVO = movieService.getMovieVO(movie, request);
        movieShowVO.setMovieVO(movieVO);
        Theater theater = theaterService.getById(movieShowVO.getTheaterId());
        TheaterVO theaterVO = theaterService.getTheaterVO(theater, request);
        movieShowVO.setTheaterVO(theaterVO);
        // todo 可以根据需要为封装对象补充值，不需要的内容可以删除
        // region 可选
        // 1. 关联查询用户信息

        // 2. 已登录，获取用户点赞、收藏状态

        // endregion

        return movieShowVO;
    }

    /**
     * 分页获取上映封装
     *
     * @param movieShowPage
     * @param request
     * @return
     */
    @Override
    public Page<MovieShowVO> getMovieShowVOPage(Page<MovieShow> movieShowPage, HttpServletRequest request) {
        List<MovieShow> movieShowList = movieShowPage.getRecords();
        Page<MovieShowVO> movieShowVOPage = new Page<>(movieShowPage.getCurrent(), movieShowPage.getSize(), movieShowPage.getTotal());
        if (CollUtil.isEmpty(movieShowList)) {
            return movieShowVOPage;
        }
        // 对象列表 => 封装对象列表
        List<MovieShowVO> movieShowVOList = movieShowList.stream().map(movieShow -> {

            return getMovieShowVO(movieShow,request);
        }).collect(Collectors.toList());

        // todo 可以根据需要为封装对象补充值，不需要的内容可以删除
        // region 可选
        // 1. 关联查询用户信息

        // 2. 已登录，获取用户点赞、收藏状态

        // 填充信息

        // endregion

        movieShowVOPage.setRecords(movieShowVOList);
        return movieShowVOPage;
    }

}
